﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;

namespace DataAccess
{
    /// <summary>
    /// 标识要数据库执行事务的一组方法
    /// </summary>
    public class Transaction : Database, IDisposable
    {

        private DbTransaction dbTransaction = null;
        private DbConnection conn = null;
        private System.Data.IsolationLevel isolationLevel = System.Data.IsolationLevel.Unspecified;

        internal Transaction(DbProviderFactory providerFactory, string connectionString)
            : this(providerFactory, connectionString, System.Data.IsolationLevel.Unspecified)
        {
        }

        internal Transaction(DbProviderFactory dbProviderFactory, string connectionString, System.Data.IsolationLevel isolationLevel)
        {
            this.dbProviderFactory = dbProviderFactory;
            this.connectionString = connectionString;
            this.isolationLevel = isolationLevel;
            this.conn = this.dbProviderFactory.CreateConnection();
            this.conn.ConnectionString = this.connectionString;
            this.conn.Open();
            this.dbTransaction = this.conn.BeginTransaction(isolationLevel);
        }

        protected override bool SetTransaction(System.Data.Common.DbCommand cmd)
        {
            if (cmd == null)
            {
                throw new ArgumentNullException("cmd");
            }
            base.SetTransaction(cmd);
            if (this.dbTransaction.Connection == null)
            {
                this.dbTransaction = conn.BeginTransaction(this.isolationLevel);
            }
            cmd.Transaction = this.dbTransaction;
            return true;
        }

        protected override DbConnection CreateConnection()
        {
            return conn;
        }

        /// <summary>
        /// 提交数据库事务
        /// </summary>
        public void Commit()
        {
            dbTransaction.Commit();
        }

        /// <summary>
        /// 从挂起状态回滚事务
        /// </summary>
        public void Rollback()
        {
            dbTransaction.Rollback();
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                dbTransaction.Dispose();
                if (conn != null)
                {
                    conn.Dispose();
                }
            }
        }
    }
}
